home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_07_03 / v7n3083a.txt < prev    next >
Text File  |  1989-03-04  |  16KB  |  626 lines

  1.  
  2.  
  3. /* next_string() reads the header file and returns the next NON-COMMENT */
  4. /* string in the file, or NULL if end-of-file is reached */
  5. /* *f is the file pointer for the header file */
  6.  
  7. char *next_string(f)
  8. FILE *f;
  9. {
  10.     int num_fields; /* number of fields read & assigned by fscanf() */
  11.     static char instring[256];  /* buffer for fscanf() */
  12.         /* WARNING: While INSTRING is declared as a local variable, its */
  13.         /* actual scope is more global. INSTRING is declared STATIC */
  14.         /* because it is accessed by other functions via the STRING */
  15.         /* pointer.  The contents of INSTRING must remain valid beyond */
  16.         /* the life of the next_string() call.                      */
  17.  
  18.     char *string; /* pointer to INSTRING */
  19.  
  20.     num_fields=fscanf(f,"%s",instring);
  21.     string=instring;
  22.  
  23.         /* throw away the comments */
  24.     if(!strncmp("/*", string, 2))
  25.     {
  26.         do
  27.         {
  28.         num_fields=fscanf(f,"%s",string);
  29.         } while( strncmp("*/",&string[strlen(string)-2],2) && (num_fields != EOF));
  30.  
  31.         /* get the next string after the close of the comment */
  32.         /* to return.  Make sure that the next string is not also */
  33.         /* a comment by using the recursive call */
  34.         string=next_string(f);
  35.     }
  36.  
  37.     if(num_fields==EOF)
  38.         string=NULL;
  39.  
  40.     return(string);
  41.  
  42. }
  43.  
  44.  
  45.  
  46.  
  47.  
  48. Listing 1: The main parsing function of h_filter.
  49.  
  50.  
  51. ACUITY_H                                acuity.h
  52. ACUITY_SCALE_FACTOR                     acuity.h
  53. CORRECT                                 acuity.h
  54. DATAFILE                                acuity.h
  55. LARGER                                  acuity.h
  56. NEW_SIZE                                acuity.h
  57. NO_RESPONSE                             acuity.h
  58. SEARCH                                  acuity.h
  59. SMALLER                                 acuity.h
  60. STDOUT                                  acuity.h
  61. STDPRN                                  acuity.h
  62. TARG_DOWN                               acuity.h
  63. TARG_LEFT                               acuity.h
  64. TARG_RIGHT                              acuity.h
  65. TARG_UP                                 acuity.h
  66. TRACK                                   acuity.h
  67. VERTICAL_DASH                           acuity.h
  68. WRONG                                   acuity.h
  69.  
  70.  
  71.  
  72. Table 1: Sample output of h_filter.
  73.  
  74. AB_END                                  acu_menu.h
  75. ABS                                     itex100.h
  76. ABSOLUTE                                itex100.h
  77. ACU_MENU_H                              acu_menu.h
  78. ACUITY_ARRAY_SIZE                       acu_menu.h
  79. ACUITY_H                                acuity.h
  80. ACUITY_SCALE_FACTOR                     acuity.h
  81. AD_IN                                   dt2808.h
  82. ADD                                     itex100.h
  83. ALLOCATION_ERROR                        itex100.h
  84. ALT                                     keys.h
  85. AND                                     itex100.h
  86. ANSI_H                                  ansi.h
  87. ANY_BUTTON                              cont_lib.h
  88. aslope                                  scotoma.h
  89. AUTO_PAUSE                              scotoma.h
  90.  
  91.  
  92.  
  93.  
  94.  
  95. Table 2: Fragment of sample output from 
  96.          h_merge, including the 'a' entries
  97.          from table 1.
  98.  
  99. /* h_filter.c is a utility for extracting names of #define'd constants */
  100. /* and macros, structs, unions, and typedefs from a header file and */
  101. /* creating an alphabetical listing file of the names, like this: */
  102. /* NAME    HEADER.H filename, one entry per line in the file. */
  103. /* All header.h filename entries are the same in the output file */
  104. /* The output file can be used to create a cross-reference list of */
  105. /* header file names for a library by combining the appropriate */
  106. /* alphabetical lists using h_merge.c, a companion utility. */
  107. /*                                                              */
  108. /* WARNING: h_filter.c uses a simplified version of C grammar, in */
  109. /* which comment delimiters and keywords are assumed to be preceded */
  110. /* and followed by either a space or a newline.  Valid C code will not */
  111. /* necessarily be parsed properly.  Further, it is assumed that all */
  112. /* struct and union definitions have names, i.e., struct {int a;char b;}c; */
  113. /* will be viewed as having the name "int". */
  114. /*                                                                      */
  115. /* Written by T. Clune 8/88.  Copyright (c) 1988, Eye Research Institute */
  116. /* Boston, MA.  Permission is granted to individuals to use this utility */
  117. /* for noncommercial applications.  All commercial rights are reserved. */
  118.  
  119. /* Known MS C-specific aspects of this program are: use of process.h header */
  120. /* file to decalre exit() and use of strcmpi(), which is a Microsoft function */
  121. /* like strcmp() except that the string comparison is case-insensitive.  A */
  122. /* usable substitute for strcmpi() is available in my file strcmpi.c. */
  123.  
  124.  
  125. #include <stdio.h>
  126. #include <process.h>    /* MS C header that declares exit() */
  127. #include <string.h>
  128. #include <ctype.h>
  129. #include <malloc.h>
  130. #include <search.h>
  131.  
  132. #define MAXPTRS 500     /* max number of names supported from the .h file */
  133. #define PATH_CHAR '\\'  /* path delimiter in MS-DOS */
  134. #define DRIVE_CHAR ':' /* drive designator in MS-DOS */
  135.  
  136.  
  137. static char *ptr[MAXPTRS];   /* ptrs to names of definitions in .h file */
  138. static int numptrs; /* the number of names that are actually in the file */
  139.  
  140. char * next_string();
  141. char * lose_braces();
  142. void extract_names(), put_name();
  143. void make_list();
  144. int compare();
  145.  
  146.  
  147. /* main() Usage: h_filter foo.h bar.srt,                                 */
  148. /* where FOO.H is the name of the header file to work on                 */
  149. /* and BAR.SRT is the alphabetically-sorted list of FOO.H defined names. */
  150.  
  151. main(argc, argv)
  152. int argc;
  153. char *argv[];
  154. {
  155.  
  156.     FILE *f;
  157.     numptrs=0;  /* initialize number of names variable */
  158.  
  159.     if(argc != 3)
  160.     {
  161.     printf("Usage: %s foo.h bar.srt,\n", argv[0]);
  162.     printf("\twhere FOO.H is the name of the header file to work on,\n");
  163.     printf("\t and BAR.SRT is the alphabetically-sorted list of FOO.H defined names,\n");
  164.     exit(-1);
  165.     }
  166.  
  167.  
  168.     if((f=fopen(argv[1], "r"))==NULL)
  169.     {
  170.     printf("Unable to open %s\n", argv[1]);
  171.     exit(-1);
  172.     }
  173.  
  174.     extract_names(f);
  175.  
  176.     fclose(f);
  177.  
  178.     make_list(argv[1], argv[2]);
  179.  
  180. }
  181.  
  182.  
  183.  
  184.  
  185.  
  186. /* compare() is the function for qsort() comparisons in make_list() */
  187.  
  188. int compare(a, b)
  189. char **a, **b;
  190. {
  191.     return(strcmpi(*a, *b));
  192. }
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199. /* extract_names() parses the header file, throwing away everything except */
  200. /* #define, struct, union, or typedef names, and sends the names to put_names() */
  201. /* for storage in malloc()ed space. *f is the file pointer for the header file */
  202.  
  203. void extract_names(f)
  204. FILE *f;
  205. {
  206.     char *string, oldstring[256], *str_ptr;
  207.  
  208.     do
  209.     {
  210.  
  211.     string=next_string(f);
  212.  
  213.         /* get the names that immediately follow a keyword */
  214.         /* (i.e., #define name, struct name, or union name) */
  215.     if(!strcmp("#define", string))
  216.     {
  217.  
  218.         string=next_string(f);
  219.         put_name(string);
  220.     }
  221.  
  222.         /* get the '#      define' names */
  223.     if(!strcmp("#", string))
  224.     {
  225.         string=next_string(f);
  226.         if(!strcmp("define", string))
  227.         {
  228.         string=next_string(f);
  229.         put_name(string);
  230.         }
  231.     }
  232.  
  233.         /* get struct or union name and throw away the braces */
  234.     if( (!strcmp("struct", string)) || (!strcmp("union", string)) )
  235.     {
  236.  
  237.         string=next_string(f);
  238.         put_name(string);
  239.         /* it's either 'struct name{' */
  240.         if(str_ptr=strchr(string, '{'))
  241.         string=lose_braces(f, str_ptr);
  242.         else
  243.         {
  244.             /* or 'struct name {' */
  245.         string=next_string(f);
  246.         string=lose_braces(f, string);
  247.         }
  248.     }
  249.  
  250.  
  251.         /* for typedefs, the name is the last thing before ';' */
  252.         /* i.e., typedef identifier {...} name;                */
  253.     if(!strcmp("typedef", string))
  254.     {
  255.         for(;;)
  256.         {
  257.         string=next_string(f);
  258.         if(str_ptr=strchr(string, '{'))
  259.             string=lose_braces(f, str_ptr);
  260.  
  261.             /* the end of the typedef condition */
  262.            if(str_ptr=strrchr(string,';'))
  263.            {
  264.             /* this selects between 'name ;' and  'name; ' */
  265.             /* if the former,